﻿/**
 * 
 * @file FITKTriMeshGenEarCut.h
 * @brief 利用割耳法生成三角形网格，要求所有的输入点近似在一个平面内
 * @author LiBaojun (libaojunqd@foxmail.com)
 * @date 2024-10-30
 * 
 */
#ifndef __FITK_TRIANGLE_MESHGEN_EARCUT_H__
#define __FITK_TRIANGLE_MESHGEN_EARCUT_H__

#include "FITK2DMeshToolsAPI.h"
#include "FITK_Kernel/FITKCore/FITKAbstractObject.hpp"
#include <QList>
 
namespace Core
{
    class FITKNode;
    class FITKPoint;
}

namespace Interface
{
    class FITKAbstractElement;
    /**
     * @brief   利用割耳法生成三角形网格，要求所有的输入点近似在一个平面内
     * @author liuzhonghua (liuzhonghuaszch@163.com)
     * @date   2024-10-25
     */
    class FITK2DMeshToolsAPI FITKTriMeshGenEarCut :public Core::FITKAbstractObject
    {

    public:
        /**
         * @brief Construct a new FITKTriMeshGenEarCut object
         * @author liuzhonghua (liuzhonghuaszch@163.com)
         * @date   2024-10-25
         */
        explicit FITKTriMeshGenEarCut() = default;
        /**
         * @brief Destroy the FITKTriMeshGenEarCut object
         * @author liuzhonghua (liuzhonghuaszch@163.com)
         * @date   2024-10-25
         */
        virtual ~FITKTriMeshGenEarCut() = default;

        /**
         * @brief    设置点数据
         * @param[i] nodeList 
         * @return   void
         * @author   liuzhonghua (liuzhonghuaszch@163.com)
         * @date     2024-10-25
         */
        void setPointList(const QList<Core::FITKNode*>& nodeList);

        /**
         * @brief 生成三角面
         * @return true  生成成功
         * @return false  生成失败
         * @author LiBaojun (libaojunqd@foxmail.com)
         * @date 2024-10-30
         */
        bool generateMesh();
        /**
         * @brief 获取三角形列表
         * @return QList<FITKAbstractElement*> 
         * @author LiBaojun (libaojunqd@foxmail.com)
         * @date 2024-10-30
         */
        QList<FITKAbstractElement*> getTriangle() const;

    private:
        /**
         * @brief    开始生成三角面片
         * @return   void
         * @author   liuzhonghua (liuzhonghuaszch@163.com)
         * @date     2024-10-29
         */
        void startGenTriPatch();
        /**
         * @brief    多边形法向
         * @return   void
         * @author   liuzhonghua (liuzhonghuaszch@163.com)
         * @date     2024-10-25
         */
        void calPolygonNormal();
     
        /**
         * @brief    判断p2点的凹凸性,根据多边形的法向与三角形的法向的夹角进行判断，夹角小于90度为凸点，夹角大于90度为凹点
         * @param[i] p1 
         * @param[i] p2 
         * @param[i] p3 
         * @return   bool 凹凸性 ：true 凸性 false 凹性
         * @author   liuzhonghua (liuzhonghuaszch@163.com)
         * @date     2024-10-25
         */
        bool isPointConcaveConvex(Core::FITKNode* p1, Core::FITKNode* p2, Core::FITKNode* p3);
        /**
         * @brief    获取判断该三角形中是否存在多边形的其他点
         * @param[i] p1 
         * @param[i] p2 
         * @param[i] p3 
         * @return   bool
         * @author   liuzhonghua (liuzhonghuaszch@163.com)
         * @date     2024-10-25
         */
        bool isContainsOtherPoint(Core::FITKNode* p1, Core::FITKNode* p2, Core::FITKNode* p3);

    private:
        /**
         * @brief  点的数据链表
         * @author liuzhonghua (liuzhonghuaszch@163.com)
         * @date   2024-10-25
         */
        QList<Core::FITKNode*> _nodeList{};
        /**
         * @brief  凸点链表
         * @author liuzhonghua (liuzhonghuaszch@163.com)
         * @date   2024-10-25
         */
        QList<Core::FITKNode*> _convexNodeList{};
        /**
         * @brief  多边形法向
         * @author liuzhonghua (liuzhonghuaszch@163.com)
         * @date   2024-10-25
         */
        double _polygonNormal[3]{0, 0, 0};
        /**
         * @brief  三角面片单元
         * @author liuzhonghua (liuzhonghuaszch@163.com)
         * @date   2024-10-25
         */
        QList<FITKAbstractElement*> _triElement{};
    };
}

#endif // !__FITKTRIPATCHESPROCESS_H__
